package timelist

import (
	"gitee.com/zhongguo168a/gocodes/datax/arrayx"
)

func NewTimeList() *TimeList {
	t := &TimeList{}
	return t
}

// 定时器
type TimeList struct {
	//timePerFrame float64
	// 定时器列表
	itemList []*TimeItem
	// 计数器
	itemCount int
	// 静止
	InStasis bool
	//
	lastNow int
}

func (timer *TimeList) GetItems() []*TimeItem {
	return timer.itemList
}
func (timer *TimeList) Dispose() {
	if timer == nil {
		return
	}
	for _, val := range timer.itemList {
		val.Dispose()
	}
	timer.itemList = nil
}

// 重置定时器到初始状态
func (timer *TimeList) Reset() {
	for _, val := range timer.itemList {
		if !val.Removed {
			val.Reset()
			pools.PutItem(val)
		}
	}
	timer.itemList = timer.itemList[:0]
	timer.itemCount = 0
	timer.InStasis = false
}

func (timer *TimeList) NextItemId() int {
	timer.itemCount++
	return timer.itemCount
}

// 目标时间
func (timer *TimeList) CreateItem(completeTime int, host ITimeHandler, params ...interface{}) *TimeItem {
	var item = CreateTimerItem()

	item.Id = timer.NextItemId()
	//item.Target = host.GetFactoryLink()
	item.Target = host
	item.CreateParams = params
	item.Complete = completeTime
	item.Removed = false
	timer.addItem(item)
	return item
}

func (timer *TimeList) RefreshById(timerId int) {
	item := timer.GetTimerById(timerId)
	if item != nil {
		timer.Refresh(item)
	}
}

func (timer *TimeList) Refresh(item *TimeItem) {
	timer.addItem(item)
}

func (timer *TimeList) addItem(item *TimeItem) {
	item.Removed = false

	var index = 0
	for i := len(timer.itemList) - 1; i >= 0; i-- {
		var t = timer.itemList[i]
		if item.Complete > t.Complete {
			continue
		}

		index++
	}

	var a = timer.itemList
	a = append(a, nil)           // a = [ 0, 1, 2, 3, 4, 0 ]
	copy(a[index+1:], a[index:]) // a = [ 0, 1, 2, 2, 3, 4 ]
	a[index] = item
	timer.itemList = a
}

func (timer *TimeList) GetTimerById(id int) *TimeItem {
	for _, val := range timer.itemList {
		if val.Id == id {
			return val
		}
	}
	return nil
}

func (timer *TimeList) RemoveById(timerId int) {
	if timerId == 0 {
		return
	}

	item := timer.GetTimerById(timerId)
	if item == nil {
		return
	}
	timer.Remove(item)
}

func (timer *TimeList) Remove(item *TimeItem) {
	if item == nil {
		return
	}
	if item.Removed {
		return
	}

	var i = arrayx.IndexOf(len(timer.itemList), func(i int) bool {
		return timer.itemList[i] == item
	})

	if i != -1 {
		a := timer.itemList
		a[i] = a[len(a)-1]
		a[len(a)-1] = nil
		a = a[:len(a)-1]

		timer.itemList = a
	}

	item.Reset()
	pools.PutItem(item)

}

// 遍历时间项，执行并抛弃当前时间的时间项
func (timer *TimeList) forRange(handler func(host interface{}, createParams, updateParams []interface{})) {
	// 复制列表, 避免hander执行后, 会添加新元素到列表中
	// 删除元素通过Item.Removed处理
	var timerList = make([]*TimeItem, len(timer.itemList), cap(timer.itemList))
	copy(timerList, timer.itemList)

	var removes []*TimeItem

	for i := len(timerList) - 1; i >= 0; i-- {
		item := timerList[i]
		if timer.lastNow < item.Complete {
			break
		}
		if item.Removed == false {
			handler(item.Target, item.CreateParams, item.UpdateParams)
		}
		// 因为handler有可能把item删除
		if item.Removed == false {
			removes = append(removes, item)
		}
	}

	for _, item := range removes {
		// 删除TimerList
		//timer.Remove(item)
		var i = arrayx.IndexOf(len(timer.itemList), func(i int) bool {
			return timer.itemList[i] == item
		})

		if i != -1 {
			a := timer.itemList
			a[i] = a[len(a)-1]
			a[len(a)-1] = nil
			a = a[:len(a)-1]

			timer.itemList = a
		}
		item.Reset()
		pools.PutItem(item)
	}
}

func (timer *TimeList) Update(now int, ctx interface{}, params ...interface{}) {
	//f := timer.factory
	timer.lastNow = now
	timer.forRange(func(host interface{}, createParams, updateParams []interface{}) {
		if host == nil {
			return
		}
		obj := host.(ITimeHandler)
		obj.UpdateTimerSet(ctx, createParams, updateParams)
	})
}
